#ifndef JOYEVT_H
#define JOYEVT_H

// This is my own SDL-based joystick handler, since wxJoystick is brain-dead.
// It's geared towards keyboard emulation

// To use, create a wxSDLJoy object Add() the joysticks you want to monitor.
// wxSDLJoy derives from wxTimer, so you can pause it with Stop() and
// resume with Start().
//
//   The target window will receive EVT_SDLJOY events of type wxSDLJoyEvent.

#include <wx/event.h>
#include <wx/timer.h>

typedef struct wxSDLJoyState wxSDLJoyState_t;

class wxSDLJoy : public wxTimer
{
public:
	// if analog, send events for all axis movement
	// otherwise, only send events when values cross the 50% mark
	// and max out values
	wxSDLJoy(bool analog = false);
	// but flag can be set later
	void SetAnalog(bool analog = true) { digital = !analog; };
	// send events to this handler
	// If NULL (default), send to window with keyboard focus
	wxEvtHandler* Attach(wxEvtHandler*);
	// add another joystick to the list of polled sticks
	// -1 == add all
	// If joy > # of joysticks, it is ignored
	// This will start polling if a valid joystick is selected
	void Add(int joy = -1);
	// remove a joystick from the polled sticks
	// -1 == remove all
	// If joy > # of joysticks, it is ignored
	// This will stop polling if all joysticks are disabled
	void Remove(int joy = -1);
	// query if a stick is being polled
	bool IsPolling(int joy);
	// query # of joysticks
	int GetNumJoysticks() { return njoy; }
	// query # of axes on given joystick
	// 0 is returned if joy is invalid
	int GetNumAxes(int joy);
	// query # of hats on given joystick
	// 0 is returned if joy is invalid
	int GetNumHats(int joy);
	// query # of buttons on given joystick
	// 0 is returned if joy is invalid
	int GetNumButtons(int joy);

	virtual ~wxSDLJoy();
protected:
	bool digital;
	int njoy;
	wxSDLJoyState_t* joystate;
	wxEvtHandler* evthandler;
	bool nosticks;
	void Notify();
};

enum
{
	// The types of supported controls
	// values are signed-16 for axis, 0/1 for button
	// hat is bitmask NESW/URDL
	WXSDLJOY_AXIS, WXSDLJOY_HAT, WXSDLJOY_BUTTON
};

class wxSDLJoyEvent : public wxCommandEvent
{
	friend class wxSDLJoy;
public:
	// Default constructor
	wxSDLJoyEvent(wxEventType commandType = wxEVT_NULL, int id = 0) :
		wxCommandEvent(commandType, id) {}
	// accessors
	unsigned short GetJoy() { return joy; }
	unsigned short GetControlType() { return ctrl_type; }
	unsigned short GetControlIndex() { return ctrl_idx; }
	short GetControlValue() { return ctrl_val; }
	short GetControlPrevValue() { return prev_val; }
	// required for PostEvent, apparently
	wxEvent* Clone();
protected:
	unsigned short joy;
	unsigned short ctrl_type;
	unsigned short ctrl_idx;
	short ctrl_val;
	short prev_val;
};

// Note: this means sdljoy can't be part of a library w/o extra work
DECLARE_LOCAL_EVENT_TYPE(wxEVT_SDLJOY, -1)
typedef void (wxEvtHandler::*wxSDLJoyEventFunction)(wxSDLJoyEvent &);
#define EVT_SDLJOY(fn) \
    DECLARE_EVENT_TABLE_ENTRY(wxEVT_SDLJOY, wxID_ANY, wxID_ANY, \
                  (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction) \
                  wxStaticCastEvent(wxSDLJoyEventFunction, &fn), (wxObject *)NULL), \

#endif /* JOYEVT_H */
